package club.fuwenhao.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.Data;

/**
 * @program: fwh-netty
 * @description: netty服务端
 * @author: fwh
 * @date: 2021-10-28 12:51
 **/
@Data
public class BaseNettyServer {
    /**
     * 服务端口
     */
    private int port = 9000;
    /**
     * 服务端处理类
     */
    private BaseNettyServerHandler baseNettyServerHandler;

    /**
     * 此处返回对象
     *
     * @param port
     * @return
     */
    public BaseNettyServer setPort(int port) {
        this.port = port;
        return this;
    }

    /**
     * 此处返回对象
     *
     * @param baseNettyServerHandler
     * @return
     */
    public BaseNettyServer setBaseNettyServerHandler(BaseNettyServerHandler baseNettyServerHandler) {
        this.baseNettyServerHandler = baseNettyServerHandler;
        return this;
    }

    /**
     * 服务端启动
     *
     * @param
     * @return void
     * @author fuwenhao
     * @date 2021/10/28 1:03 下午
     */
    public boolean start() throws InterruptedException {
        NioEventLoopGroup boosEventLoopGroup = new NioEventLoopGroup();
        NioEventLoopGroup workEventLoopGroup = new NioEventLoopGroup();
//        try {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(boosEventLoopGroup, workEventLoopGroup)
                .channel(NioServerSocketChannel.class)
                //队列的最大长度
                .option(ChannelOption.SO_BACKLOG, 1024)
//                .option(ChannelOption.SO_TIMEOUT, 120)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childOption(ChannelOption.TCP_NODELAY, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ObjectEncoder())
//                                .addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)))
                                .addLast(new LengthFieldBasedFrameDecoder(20 * 1024, 0, 2))
                                //超时心跳检测设置
                                .addLast(new IdleStateHandler(20, 10, 1))
                                .addLast(baseNettyServerHandler);
                    }
                });
        ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
        return channelFuture.isSuccess();
//        } finally {
//            boosEventLoopGroup.shutdownGracefully();
//            workEventLoopGroup.shutdownGracefully();
//        }
    }
}
